import axios from 'axios'
import store from '@/store'
import { Message } from 'element-ui'
import message from 'element-ui/packages/message'
import router from '@/router'
import { getTimeStamp } from '@/utils/auth'

// 和后端协商：你token过期的时间是多少？
// 开发的时候：超时时间设置长一点，不然会一直提示token过期
const timeOut = 2 * 24 * 60 * 60 * 1000 // 单位为ms  表示的是1小时

const checkTimeOut = () => {
// 如果返回true证明过期了
// 如果返回false没有过期的
//  用当前的时间-登录时候存储的时间 > 超时的时间
  return Date.now() - getTimeStamp() > timeOut
}

// token失效前端主动介入的处理逻辑
// 核心判断：本地存储一个过期的时间，每一次请求的时候，判断token存储在本地的时候是否超过了这个过期时间
//         如果超过了就过期了，否则就是可用的

// 只要当前token过期了，或者token不可用了，后端都会返回401
// 我们拿到401的状态码 ==> token不能用了 ==> 让用户重新登录
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API // 读取的是环境变量配置文件里面定义的变量
})

service.interceptors.request.use(config => {
//  注入token
//  判断是否有token，如果有再进行注入
  const token = store.getters.token
  if (token) {
    // 判断token是否过期
    if (checkTimeOut()) {
      //  执行退出登录的操作
      store.dispatch('user/logOut')
      router.push('/login')
      message.error('登录信息过期')
      return Promise.reject(new Error('token过期'))
    }
    config.headers.Authorization = `Bearer ${token}`
  }
  return config // 必须返回一个修改好的配置项
}, err => {
  return Promise.reject(err)
})
// 响应拦截器 （response）
// 什么时候走成功？什么时候走失败？
service.interceptors.response.use(response => {
  // 只有200-300之间的状态码会走成功，其余的状态码会走失败
  const { message, success, data } = response.data
  if (success) {
    return data
  } else {
    //  接口请求出错，让接口报错
    Message.error(message)
    return Promise.reject(new Error(message))
  }
}, err => {
  // 接口状态码出错的时候，判断它的状态码是不是401，如果是401说明token过期了，就需要重新登录
  // 401判断token失效提倡的一种规范的做法
  // 我们人资接口就是按照这种规范去设计的接口
  // 所以我们可以直接判断401
  // 如果是我们公司开发的时候，先跟后端确认一下，如果token过期，他会给我们返回什么？按照后端返回的数据格式去进行判断
  if (err.response.status === 401) {
    //  退出登录
    store.dispatch('user/logOut')
    //  跳转登录界面
    router.push('/login')
  }
  // 不需要在接口具体请求的地方进行提示
  Message.error(err.response.data.message || '系统错误，请稍后重试')
  return Promise.reject(err)
})

// 当前配置好的axios实例导出
// 搭建项目的时候不涉及业务逻辑，搭建基本架子，再去填充代码
export default service

// 怎么发布上线的？自动发布平台
// 1、中小型公司：jenkins 持续集成的平台（部署到服务器上面的）
//      1、把你们的git仓库和服务器做关联
//      2、监听git提交命令
//      3、开发环境：只要你git代码提交到development(约定测试)分支，自动触发部署到测试环境（只有你们自己能看到）
//      4、可以在服务器端自动拉取代码，执行打包命令，把打包之后的文件复制到服务器上面的静态服务目录

// 测试环境：开发环境的代码，开发环境的数据(数据库) 分支-dev分支 数据->测试环境假数据
// 预发环境：开发环境的代码，真实环境的数据（数据库） 代码提交到realease 数据 -> 真实数据
// 测试流程：测试环境 -> 预发环境 -> 上线

// 正式环境，一般情况不会配置自动部署
// jenkins平台（后台管理系统）手动部署
// release(预发分支)预发环境测试完毕之后, 直接把当前代码部署上线，开发手动在jenkins后台点击部署（手动部署）
// 上线之后，测试人员还需要一轮测试，release合并到master，完成一次发布

// linux系统
// 命令行登录服务器
// 通过复制文件的命令去本地复制到服务器
